package practice.connectionpool;

import java.sql.Connection;
import java.util.LinkedList;
import java.util.Queue;

/**
 * 使用等待超市模式 构造一个数据库连接池
 * 
 * @author insight
 * @since 2021/9/9
 */
public class ConnectionPool {
    private final Queue<Connection> connectionPool;

    public ConnectionPool(int initialSize) {
        connectionPool = new LinkedList<>();
        if (initialSize < 0) throw new IllegalArgumentException("Illegal initialSize!");

        for (int i = 0; i < initialSize; i++) {
            connectionPool.offer(ConnectionDriver.createConnection());
        }
    }

    public void releaseConnection(Connection connection) {
        if (connection != null) {
            synchronized (connectionPool) {
                connectionPool.offer(connection);
                connectionPool.notifyAll();
            }
        }
    }
    
    public Connection getConnection(long mills) throws InterruptedException {
        synchronized (connectionPool) {
            // 无计时等待
            if (mills <= 0) {
                while (connectionPool.isEmpty()) {
                    connectionPool.wait();
                }

                return connectionPool.poll();
            }

            long end = System.currentTimeMillis() + mills;
            long remain = mills;
            while (connectionPool.isEmpty() && remain > 0) {
                connectionPool.wait(remain);
                remain = end - System.currentTimeMillis();
            }

            return connectionPool.isEmpty() ? null : connectionPool.poll();
        }
    }
}